package com.searchengine.service.impl;

import com.searchengine.entity.KeywordWeight;
import com.searchengine.entity.SearchHistory;
import com.searchengine.entity.SearchResult;
import com.searchengine.entity.User;
import com.searchengine.repository.KeywordWeightRepository;
import com.searchengine.repository.SearchHistoryRepository;
import com.searchengine.repository.SearchResultRepository;
import com.searchengine.service.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 搜索服务实现类
 */
@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private SearchHistoryRepository searchHistoryRepository;

    @Autowired
    private SearchResultRepository searchResultRepository;

    @Autowired
    private KeywordWeightRepository keywordWeightRepository;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${baidu.api.url}")
    private String baiduApiUrl;

    @Value("${baidu.api.key}")
    private String baiduApiKey;

    @Override
    @Transactional
    public List<SearchResult> search(String keyword, Long userId, String ipAddress) {
        // 记录搜索历史
        SearchHistory searchHistory = recordSearchHistory(keyword, userId, ipAddress);

        // 从百度API获取搜索结果
        List<Map<String, Object>> rawResults = fetchFromBaiduAPI(keyword);

        // 转换为SearchResult对象
        List<SearchResult> searchResults = convertToSearchResults(rawResults, searchHistory);

        // 根据关键词权重排序
        List<SearchResult> sortedResults = sortByKeywordsWeight(searchResults, keyword);

        // 调用AI增强搜索结果
        List<SearchResult> enhancedResults = enhanceWithAI(sortedResults, keyword);

        // 保存搜索结果
        saveSearchResults(enhancedResults);

        return enhancedResults;
    }

    @Override
    public List<Map<String, Object>> fetchFromBaiduAPI(String keyword) {
        // 构建百度API请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("q", keyword);
        params.put("apikey", baiduApiKey);

        try {
            // 调用百度API获取搜索结果
            // 这里只是示例，实际API调用需要根据百度API文档进行调整
            Map<String, Object> response = restTemplate.getForObject(baiduApiUrl, Map.class, params);
            return (List<Map<String, Object>>) response.get("results");
        } catch (Exception e) {
            // 异常处理，返回空结果
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    @Override
    public List<SearchResult> sortByKeywordsWeight(List<SearchResult> results, String keyword) {
        // 获取当前有效的关键词权重
        Date now = new Date();
        List<KeywordWeight> weights = keywordWeightRepository.findByKeywordAndStartTimeLessThanEqualAndEndTimeGreaterThanEqual(
                keyword, now, now);

        // 复制结果列表，避免修改原始列表
        List<SearchResult> sortedResults = new ArrayList<>(results);

        // 按权重排序
        sortedResults.sort((a, b) -> {
            // 先按自定义权重排序
            int weightCompare = b.getWeight().compareTo(a.getWeight());
            if (weightCompare != 0) {
                return weightCompare;
            }
            // 权重相同时按原始排名排序
            return a.getRank().compareTo(b.getRank());
        });

        // 重新分配排名
        for (int i = 0; i < sortedResults.size(); i++) {
            sortedResults.get(i).setRank(i + 1);
        }

        return sortedResults;
    }

    @Override
    public List<SearchHistory> getUserSearchHistory(Long userId, Integer limit) {
        List<SearchHistory> historyList = searchHistoryRepository.findByUserIdOrderByCreatedAtDesc(userId);
        if (limit != null && limit > 0 && historyList.size() > limit) {
            return historyList.subList(0, limit);
        }
        return historyList;
    }

    @Override
    @Transactional
    public void clearUserSearchHistory(Long userId) {
        // 获取用户的搜索历史
        List<SearchHistory> historyList = searchHistoryRepository.findByUserIdOrderByCreatedAtDesc(userId);
        
        // 删除关联的搜索结果
        for (SearchHistory history : historyList) {
            searchResultRepository.deleteBySearchHistoryId(history.getId());
        }
        
        // 删除搜索历史
        searchHistoryRepository.deleteByUserId(userId);
    }

    @Override
    @Transactional
    public SearchHistory recordSearchHistory(String keyword, Long userId, String ipAddress) {
        SearchHistory history = new SearchHistory();
        history.setKeyword(keyword);
        history.setIpAddress(ipAddress);
        
        if (userId != null) {
            User user = new User();
            user.setId(userId);
            history.setUser(user);
        }
        
        return searchHistoryRepository.save(history);
    }

    @Override
    public List<SearchResult> enhanceWithAI(List<SearchResult> results, String query) {
        // 这里是AI增强搜索结果的实现
        // 实际应用中需要调用AI大模型API
        // 目前只是返回原始结果
        return results;
    }

    /**
     * 将百度API返回的原始结果转换为SearchResult对象
     */
    private List<SearchResult> convertToSearchResults(List<Map<String, Object>> rawResults, SearchHistory searchHistory) {
        List<SearchResult> results = new ArrayList<>();
        for (int i = 0; i < rawResults.size(); i++) {
            Map<String, Object> rawResult = rawResults.get(i);
            SearchResult searchResult = new SearchResult();
            searchResult.setSearchHistory(searchHistory);
            searchResult.setTitle((String) rawResult.get("title"));
            searchResult.setUrl((String) rawResult.get("url"));
            searchResult.setDescription((String) rawResult.get("description"));
            searchResult.setWeight(BigDecimal.ZERO); // 初始权重为0
            searchResult.setRank(i + 1);
            results.add(searchResult);
        }
        return results;
    }

    /**
     * 保存搜索结果到数据库
     */
    @Transactional
    private void saveSearchResults(List<SearchResult> results) {
        searchResultRepository.saveAll(results);
    }
}